package com.xxx.rpc;

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.ConsumerCancelledException;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.ShutdownSignalException;

/**
 * Rabbit MQ使用场景六：RPC客户端
 	1：建立一个连接和通道，并声明了一个唯一的“回调”队列的答复
	2：我们订阅回调队列，这样就可以得到RPC的响应
	3：定义一个call方法用于发送当前的回调请求
	4：生成一个唯一的correlationid，然后通过while循环来捕获合适的回应
	5：我们请求信息，发送2个属性，replyTo 和correlationId
	6：然后就是等待直到有合适的回应到达
	7：while循环是做一个非常简单的工作，对于每一个响应消息，它检查是否有correlationid然后进行匹配。然后是就进行响应。
	8：最后把响应返回到客户端。

 * @author guweiqiang
 * 2018年6月14日
 */
public class RPCClient {
	
	private static final String HOST = "localhost";
	private static final String RPC_QUEUE_NAME = "rpc_queue";
	
	public static void main(String[] args) throws IOException, TimeoutException, 
		ShutdownSignalException, ConsumerCancelledException, InterruptedException {
		
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost(HOST);
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		
		String replyQueueName = channel.queueDeclare().getQueue();
		QueueingConsumer queueingConsumer  = new QueueingConsumer(channel);
		channel.basicConsume(replyQueueName, true, queueingConsumer);
		
		String corrId = UUID.randomUUID().toString();
		AMQP.BasicProperties props = new AMQP.BasicProperties().builder()
				.correlationId(corrId).replyTo(replyQueueName).build();
		
		String message = "15";
		System.out.println("RPCClient requesting fib("+message+") ");
		channel.basicPublish("", RPC_QUEUE_NAME, props, message.getBytes("UTF-8"));

		String response = "";
		while (true) {
			QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
			if(delivery.getProperties().getCorrelationId().equals(corrId)) {
				response = new String(delivery.getBody(), "UTF-8");
				channel.close();
				connection.close();
				break;
			}
		}
		System.out.println("RPCClient response: " + response);
	}

}
